package e3dds

import (
	"time"

	"gitee.com/ameise84/e3dds/internal/message"
	"gitee.com/ameise84/e3log"
)

type Message = message.Message
type Request = message.Request
type Response = message.Response
type Source = message.Source

type NetContext interface {
	OnPush(string, []byte)
}

type Service interface {
	e3log.LogMarshaller
	GetServiceID() string
	RegisterProtocolHandler(any)
	RegisterProtocolHandlerWithName(string, ProtocolHandler)
	RegisterTimerHandler(uint16, TimerHandler)
	//RegisterEventHandler(uint64, EventHandler)
	//TriggerEvent(uint64, ...any)
}

type NetService interface {
	Service
	StartNetActor(string) (NetBehavior, bool)
	StopNetActor(string)
}

type RpcService interface {
	Service
	StartRpcActor(string) (Behavior, bool)
	StopRpcActor(string)
}

type ActorFactory interface {
	TakeActor() Actor
	FreeActor(Actor)
	OnBroadcast(Request)
}

type Actor interface {
	Load(string, Behavior) error                                    ///加载
	Unload(bool)                                                    //卸载
	OnTimer(Behavior, uint16, uint32, time.Time, TimerContext) bool //触发定时器
	OnRecvMsg(Behavior, Request) bool                               //收到未注册hand的消息
}

type NetBehavior interface {
	e3log.LogMarshaller
	GetSource() *Source
	GetActor() Actor
	GetContext() any
	OnRecvNetMsg(Message) error
	BindNetContext(NetContext) //将Behavior的推送消息绑定到NetContext
	UnBindNetContext()
}

type Behavior interface {
	e3log.LogMarshaller
	GetSource() *Source
	GetActor() Actor
	BindContext(any)
	GetContext() any
	AttachServicePush(srvId, cid string) //将toSrvID,toCID的推送消息绑定到当前actor
	Push(protoc string, body []byte)
	Cast(toSrvID, toCID string, protoc string, body []byte)
	Call(toSrvID, toCID string, protoc string, body []byte, rsp Response) error
	CastFix(to *Source, protoc string, body []byte)
	CallFix(to *Source, protoc string, body []byte, rsp Response) error
	Redirect(toSrvID, toCID string, msg Request)                        //重定向消息
	ForwardCall(toSrvID, toCID string, msg Request, rsp Response) error //中转
	SetTimer(kind TimerKind, id TimerID, dur time.Duration, ctx TimerContext)
	SetTimerWithFirst(kind TimerKind, id TimerID, doTime time.Time, ctx TimerContext)
	SetTick(kind TimerKind, id TimerID, dur time.Duration, rep int, ctx TimerContext)
	SetTickWithFirst(kind TimerKind, id TimerID, firstDoTime time.Time, dur time.Duration, rep int, ctx TimerContext)
	KillTimer(kind TimerKind, id TimerID)
}
